package com.lyh.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.lyh.common.core.domain.entity.SysUser;
import com.lyh.common.enums.*;
import com.lyh.common.exception.ServiceException;
import com.lyh.common.utils.CommonUtils;
import com.lyh.common.utils.DateUtils;
import com.lyh.common.utils.StringUtils;
import com.lyh.system.domain.*;
import com.lyh.system.domain.req.GoodsEditReq;
import com.lyh.system.domain.req.GoodsPubilshReq;
import com.lyh.system.domain.req.GoodsReq;
import com.lyh.system.domain.resp.GoodsDetailResp;
import com.lyh.system.domain.vo.GoodsVo;
import com.lyh.system.mapper.*;
import com.lyh.system.service.IAssetService;
import com.lyh.system.service.IGoodsService;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.lyh.common.enums.IncomeEnum.DYNAMIC;

/**
 * 商品Service业务层处理
 *
 * @author ruoyi
 * @date 2023-04-27
 */
@Service
@Log4j2
public class GoodsServiceImpl implements IGoodsService {
    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private AssetMapper assetMapper;

    @Autowired
    private OperationInfoMapper operationInfoMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SysRelationValueMapper relationValueMapper;

    @Autowired
    private IncomeMapper incomeMapper;

    @Autowired
    private SysRelationValueMapper sysRelationValueMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private IAssetService assetService;

    /**
     * 查询商品
     *
     * @param id 商品主键
     * @return 商品
     */
    @Override
    public GoodsVo selectGoodsById(Long id) {
        return goodsMapper.selectGoodsById(id);
    }

    /**
     * 查询商品列表
     *
     * @param goods 商品
     * @return 商品
     */
    @Override
    public List<Goods> selectGoodsList(Goods goods) {
        return goodsMapper.selectGoodsList(goods);
    }

    /**
     * 新增商品
     *
     * @param goods 商品
     * @return 结果
     */
    @Override
    public int insertGoods(Goods goods) {
        goods.setCreateTime(DateUtils.getNowDate());
        return goodsMapper.insertGoods(goods);
    }

    /**
     * 修改商品
     *
     * @param goods 商品
     * @return 结果
     */
    @Override
    public int updateGoods(Goods goods) {
        goods.setUpdateTime(DateUtils.getNowDate());
        return goodsMapper.updateGoods(goods);
    }

    /**
     * 批量删除商品
     *
     * @param ids 需要删除的商品主键
     * @return 结果
     */
    @Override
    public int deleteGoodsByIds(Long[] ids) {
        return goodsMapper.deleteGoodsByIds(ids);
    }

    /**
     * 删除商品信息
     *
     * @param id 商品主键
     * @return 结果
     */
    @Override
    public int deleteGoodsById(Long id) {
        return goodsMapper.deleteGoodsById(id);
    }

    @Override
    public List<GoodsVo> selectGoods() {
        return goodsMapper.selectGoods();
    }

    @Override
    public List<Goods> selectWebGoods(GoodsReq req) {
        List<Goods> goods = goodsMapper.selectWebGoods(req);
        return goods;
    }

    @Override
    public int editGoods(GoodsEditReq req) {
        Goods goods = goodsMapper.selectById(req.getId());
        if (StringUtils.isNotEmpty(req.getName())) {
            goods.setName(req.getName());
        }
        if (StringUtils.isNotEmpty(req.getPicture())) {
            goods.setPicture(req.getPicture());
        }
        if (req.getPrice() != null) {
            goods.setPrice(req.getPrice());
        }
        if (req.getGoodsInventory() != null) {
            goods.setGoodsInventory(req.getGoodsInventory());
        }
        goods.setUpdateTime(new Date());
        if (req.getStatus() != null) {
            goods.setStatus(req.getStatus());
            if (req.getStatus() == 1) { //上架
                goods.setShelfTime(new Date());
                //检查商品内容
                if (goods.getGoodsInventory() == null || goods.getGoodsInventory() == 0l) {
                    throw new ServiceException("请填写库存！");
                }
                if (goods.getPrice() == null) {
                    throw new ServiceException("请填写商品价格！");
                }

            }
        }

        goods.setUpdateTime(new Date());
        return goodsMapper.updateById(goods);
    }

    @Override
    public int publishGoods(GoodsPubilshReq req) {
        Goods goods = new Goods();
        BeanUtils.copyProperties(req, goods);
        goods.setId(IdWorker.getId());
        if (req.getDescribeInfoList() != null && req.getDescribeInfoList().size() > 0) {
            goods.setDescribeInfo(JSONObject.toJSONString(req.getDescribeInfoList()));
        } else {
            goods.setDescribeInfo("");
        }

        List<String> mainUrlList = req.getMainUrlList();
        if (mainUrlList != null && mainUrlList.size() > 0) {
            mainUrlList.stream().forEach(c -> {
                SysRelationValue sysRelationValue = new SysRelationValue();
                sysRelationValue.setBusinessId(goods.getId().toString());
                sysRelationValue.setCode("GOODS_PICTURE");
                sysRelationValue.setValue(c);
                sysRelationValueMapper.insert(sysRelationValue);
            });
        }

        return goodsMapper.insert(goods);
    }

    @Override
    public int publishShelfGoods(GoodsPubilshReq req) {
        Goods goods = new Goods();
        BeanUtils.copyProperties(req, goods);
        goods.setId(IdWorker.getId());
        if (req.getDescribeInfoList() != null && req.getDescribeInfoList().size() > 0) {
            goods.setDescribeInfo(JSONObject.toJSONString(req.getDescribeInfoList()));
        } else {
            goods.setDescribeInfo("");
        }
        if (goods.getGoodsInventory() == null || goods.getGoodsInventory() == 0l) {
            goods.setGoodsInventory(9999l);
        }
        List<String> mainUrlList = req.getMainUrlList();
        if (mainUrlList != null && mainUrlList.size() > 0) {
            mainUrlList.stream().forEach(c -> {
                SysRelationValue sysRelationValue = new SysRelationValue();
                sysRelationValue.setBusinessId(goods.getId().toString());
                sysRelationValue.setCode("GOODS_PICTURE");
                sysRelationValue.setValue(c);
                sysRelationValueMapper.insert(sysRelationValue);
            });
        }
        //检查商品内容
        if (goods.getGoodsInventory() == null || goods.getGoodsInventory() == 0l) {
            throw new ServiceException("请填写库存！");
        }
        if (goods.getPrice() == null) {
            throw new ServiceException("请填写商品价格！");
        }
        goods.setStatus(1);
        goods.setShelfTime(new Date());
        goods.setUpdateTime(new Date());

        return goodsMapper.insert(goods);
    }

    @Override
    @Transactional
    public int publishGoodsDelete(Long id) {
        goodsMapper.deleteById(id);
        sysRelationValueMapper.delete(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getBusinessId, id)
                .eq(SysRelationValue::getCode, "GOODS_PICTURE"));
        return goodsMapper.deleteById(id);
    }

    @Override
    public GoodsDetailResp getGoodsPublish(Long id) {

        GoodsDetailResp detailResp = new GoodsDetailResp();
        Goods goods = goodsMapper.selectById(id);
        BeanUtils.copyProperties(goods, detailResp);
        List<SysRelationValue> list = sysRelationValueMapper.selectList(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getCode, "GOODS_PICTURE")
                .eq(SysRelationValue::getBusinessId, id)
                .orderByAsc(SysRelationValue::getId));
        if (list != null && list.size() > 0) {
            List<String> collect = list.stream().map(SysRelationValue::getValue).collect(Collectors.toList());
            detailResp.setMainUrlList(collect);

        }
        return detailResp;
    }

    @Override
    public void buyGoods(Long id, SysUser user, Long num, String goodsSpecs) {
        Goods goods = goodsMapper.selectById(id);
        Order order = new Order();
        order.setGoodsId(id);
        order.setGoodsNum(num);
        order.setSpecifications(goodsSpecs);
        order.setOrderNum("LYH" + CommonUtils.getRandom());
        order.setActualPayment(goods.getPrice().multiply(new BigDecimal(num)));
        order.setStatus(StoreOrderStatusEnum.wait_pay.name());
        order.setCreateTime(new Date());
        orderMapper.insert(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void purchase(Long id, Long orderId, SysUser user) {
        //购买成功之后处理
        Goods goods = goodsMapper.selectById(id);
        SysUser sysUser = sysUserMapper.selectById(user);
        if (null != goods) {
            BigDecimal price = goods.getPrice();
            //购买普通699
            if (goods.getId() == 1) {
                if (price.compareTo(new BigDecimal("699.00")) == 0) {
                    if (sysUser.getMemberLeve() == null) {
                        sysUser.setMemberLeve(0);
                    }
                    QueryWrapper<Asset> wrapper1 = new QueryWrapper<Asset>();
                    wrapper1.eq("user_id", sysUser.getUserId());
                    Asset asset1 = assetMapper.selectOne(wrapper1);
                    asset1.setEquityPoints(asset1.getEquityPoints() + goods.getGiveScore());
                    asset1.setEquityLimit(asset1.getEquityLimit().add(new BigDecimal(2000)));
                    //记录
                    assetService.addOperationInfo(sysUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.INCOME.name(),
                            OperationOriginEnum.BUG_GOODS.name(), new BigDecimal(2000));

                    assetMapper.updateById(asset1);

                    //身份
                    if (sysUser.getIsVip() != null) {
                        if (sysUser.getIsVip() == 0) {
                            sysUser.setIsVip(1);
                        } else if (sysUser.getIsVip() == 2) {
                            sysUser.setIsVip(3);
                        }
                        if (sysUser.getVipCommomTime() == null) {
                            sysUser.setVipCommomTime(new Date());
                        }
                    }
                    sysUserMapper.updateById(sysUser);
                    Long parentId = sysUser.getParentId();
                    //推荐奖励10%（只对上级）
                    if (parentId != null) {
                        //加锁

                        // RLock lock = redissonClient.getLock(key);
                        try {
                            //  if (lock.tryLock(10, 10, TimeUnit.SECONDS)) {

                            Asset asset = assetMapper.selectAssetByUserId(parentId);

                            //若上级不是普通健康大使者不返
                            SysUser parentUser = sysUserMapper.selectById(parentId);
                            Integer isVip = parentUser.getIsVip();
                            //只有是普通健康大使或都是才返
                            if (isVip == 1 || isVip == 3) {

                                if (null != asset && null != asset.getAccountBalance()) {
                                    BigDecimal decimal = goods.getPrice().multiply(new BigDecimal("0.1"));

                                    if (asset.getEquityLimit().compareTo(decimal) >= 0) {
                                        asset.setAccountBalance(asset.getAccountBalance().add(decimal));
                                        asset.setEquityLimit(asset.getEquityLimit().subtract(decimal));
                                        //记录
                                        assetService.addOperationInfo(parentId, OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                                OperationOriginEnum.ORDINARY_INCOME.name(), decimal);
                                        //添加收支记录
                                        OperationInfo oi = new OperationInfo();
                                        oi.setPrice(decimal);
                                        oi.setUserId(parentId);
                                        oi.setType(OperationTypeEnum.CASH.name());
                                        oi.setStatus(OperationStatusEnum.INCOME.name());
                                        oi.setOperationTime(new Date());
                                        oi.setOrigin(OperationOriginEnum.ORDINARY_INCOME.name());
                                        operationInfoMapper.insert(oi);
                                        assetMapper.updateById(asset);

                                        log.error("父级权益额度充足 ===== asset:" + asset.toString());
                                        log.error(sysUser.toString());

                                    } else {
                                        asset.setAccountBalance(asset.getAccountBalance().add(asset.getEquityLimit()));
                                        //添加收支记录
                                        OperationInfo oi = new OperationInfo();
                                        oi.setUserId(parentId);
                                        oi.setType(OperationTypeEnum.CASH.name());
                                        oi.setStatus(OperationStatusEnum.INCOME.name());
                                        oi.setOperationTime(new Date());
                                        oi.setPrice(asset.getEquityLimit());
                                        oi.setOrigin(OperationOriginEnum.ORDINARY_INCOME.name());
                                        operationInfoMapper.insert(oi);
                                        //记录
                                        assetService.addOperationInfo(parentId, OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                                OperationOriginEnum.ORDINARY_INCOME.name(), asset.getEquityLimit());
                                        asset.setEquityLimit(new BigDecimal(0));
                                        assetMapper.updateById(asset);

                                        log.error("父级权益额度不足 ===== asset:" + asset.toString());
                                        log.error(sysUser.toString());
                                    }
                                }
                                //  }
                                SysRelationValue relationValue = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                                        .eq(SysRelationValue::getCode, "cashMemberAdd"));
                                if (relationValue != null) {
                                    if (relationValue.getValue() != null) {
                                        relationValue.setValue(new BigDecimal(relationValue.getValue()).add(price).add(new BigDecimal("0.1")).toString());
                                    } else {
                                        relationValue.setValue(price.add(new BigDecimal("0.1")).toString());
                                    }
                                    relationValueMapper.updateById(relationValue);
                                }

                            }


                        } catch (Exception e) {
                            log.error("下单错误", e);
                            throw new ServiceException(e.getMessage());
                        }
                    }
                    //存在顶级邀请人，找到对应的资产信息 补贴奖励10%（顶级推荐人)
                    if (sysUser.getTopUserFlag() == 1 && sysUser.getTopUserId() != null) {
                        Asset asset = assetMapper.selectAssetByUserId(sysUser.getTopUserId());
                        if (null != asset && null != asset.getAccountBalance()) {
                            BigDecimal decimal = goods.getPrice().multiply(new BigDecimal("0.1"));
                            asset.setAccountBalance(asset.getAccountBalance().add(decimal));
                            assetMapper.updateById(asset);
                            //添加收支记录
                            OperationInfo oi = new OperationInfo();
                            oi.setUserId(sysUser.getTopUserId());
                            oi.setType(OperationTypeEnum.CASH.name());
                            oi.setStatus(OperationStatusEnum.INCOME.name());
                            oi.setOperationTime(new Date());
                            oi.setPrice(decimal);
                            oi.setOrigin(OperationOriginEnum.ORDINARY_INCOME.name());
                            operationInfoMapper.insert(oi);
                        }
                    }


                }
            }
            ////购买门店699
            else if (goods.getId() == 2) {
                //上级
                List<SysUser> sysUsers = sysUserMapper.indirectUser(sysUser.getMemberId());

                List<SysUser> collect = sysUsers.stream().sorted(Comparator.comparing(SysUser::getCreateTime).reversed()).collect(Collectors.toList());
                Asset asset1 = assetMapper.selectAssetByUserId(sysUser.getUserId());
                asset1.setEquityPoints(asset1.getEquityPoints() + goods.getGiveScore());
                assetMapper.updateById(asset1);

                //身份
                if (sysUser.getIsVip() != null) {
                    if (sysUser.getIsVip() == 0) {
                        sysUser.setIsVip(2);
                    } else if (sysUser.getIsVip() == 1) {
                        sysUser.setIsVip(3);
                    }
                    if (sysUser.getVipStoreTime() == null) {
                        sysUser.setVipStoreTime(new Date());
                    }
                }

                if (sysUser.getParentId() != null) {
                    //父级
                    SysUser ztUser = sysUserMapper.selectById(sysUser.getParentId());
                    collect.add(0, ztUser);
                    if (sysUser.getMemberLeve() == null) {
                        sysUser.setMemberLeve(0);
                    }
                    sysUserMapper.updateById(sysUser);
                    for (SysUser su : collect) {
                        //如果是门店长，门店长等级 返 20，40，60
                        if (su.getIsMstore() != null && su.getIsMstore()) {
                            Asset asset = assetMapper.selectAssetByUserId(su.getUserId());
                            if (asset == null) {
                                continue;
                            }
                            //门店长等级
                            QueryWrapper<SysRelationValue> qw = new QueryWrapper<>();
                            if ("1".equals(su.getMstoreLeve())) {
                                qw.eq("code", RelationTypeEnum.MDFX_ONE.name());
                            } else if ("2".equals(su.getMstoreLeve())) {
                                qw.eq("code", RelationTypeEnum.MDFX_TWO.name());
                            } else if ("3".equals(su.getMstoreLeve())) {
                                qw.eq("code", RelationTypeEnum.MDFX_THREE.name());
                            } else {
                                continue;
                            }
                            SysRelationValue relationValue = relationValueMapper.selectOne(qw);
                            BigDecimal bigDecimal = new BigDecimal(relationValue.getValue());
                            asset.setChanges(asset.getChanges().add(bigDecimal));

                            //添加收支记录
                            OperationInfo oi = new OperationInfo();
                            oi.setUserId(su.getUserId());
                            oi.setType(OperationTypeEnum.CHANGES.name());
                            oi.setStatus(OperationStatusEnum.INCOME.name());
                            oi.setOperationTime(new Date());
                            oi.setPrice(bigDecimal);
                            oi.setOrigin(OperationOriginEnum.STORE_INCOME.name());
                            operationInfoMapper.insert(oi);
                            assetMapper.updateById(asset);
                            //只返第一个门店长
                            break;
                        }
                    }

                    //普通用户购买门店699 推荐下级购买返回给用户
                    //根据父级userId 查询是否购买门店699
   /*                 List<Order> orderList = orderMapper.selectList(new LambdaQueryWrapper<Order>()
                            .eq(Order::getStatus, "wait_send")
                            .eq(Order::getUserId, ztUser.getUserId()));
                    if (orderList != null && orderList.size() > 0)
                    {*/
                    List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
                            .eq(SysUser::getParentId, ztUser.getUserId())
                            .eq(SysUser::getStatus, 0));
                    int buyGoodsNum = 0;
                    for (SysUser u : sysUserList) {
                        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("user_id", u.getUserId());
                        queryWrapper.eq("goods_id", 2l);
                        queryWrapper.ge("pay_time", ztUser.getVipStoreTime());
                        queryWrapper.in("status", Arrays.asList(StoreOrderStatusEnum.wait_send.name(),
                                StoreOrderStatusEnum.alrealy_send.name(), StoreOrderStatusEnum.success.name()));
                        List<Order> orders = orderMapper.selectList(queryWrapper);
                        for (Order order : orders) {
                            buyGoodsNum += order.getGoodsNum();
                        }
                    }
                    if (buyGoodsNum > 0 && (ztUser.getIsVip() == 2 || ztUser.getIsVip() == 3)) {
                        Asset asset = assetMapper.selectAssetByUserId(ztUser.getUserId());
                        QueryWrapper<SysRelationValue> qw = new QueryWrapper<>();
                        if (buyGoodsNum % 3 == 1) {
                            qw.eq("code", RelationTypeEnum.GMDDJL1.name());
                        } else if (buyGoodsNum % 3 == 2) {
                            qw.eq("code", RelationTypeEnum.GMDDJL2.name());
                        } else {
                            qw.eq("code", RelationTypeEnum.GMDDJL3.name());
                        }
                        SysRelationValue relationValue = relationValueMapper.selectOne(qw);
                        BigDecimal multiply = goods.getPrice().multiply(new BigDecimal(relationValue.getValue())).multiply(new BigDecimal("0.01"));

                        //添加收支记录
                        OperationInfo oi = new OperationInfo();
                        oi.setUserId(ztUser.getUserId());
                        oi.setType(OperationTypeEnum.CHANGES.name());
                        asset.setChanges(asset.getChanges() == null ? multiply : asset.getChanges().add(multiply));
                        oi.setStatus(OperationStatusEnum.INCOME.name());
                        oi.setOperationTime(new Date());
                        oi.setPrice(multiply);
                        oi.setOrigin(OperationOriginEnum.STORE_INCOME.name());
                        operationInfoMapper.insert(oi);
                        assetMapper.updateById(asset);
                    }
                    //   }
                }

            }
            SysRelationValue relationValue = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                    .eq(SysRelationValue::getCode, "cashStoreAdd"));
            if (relationValue != null) {
                if (relationValue.getValue() != null) {
                    relationValue.setValue(new BigDecimal(relationValue.getValue()).add(price).add(new BigDecimal("0.05")).toString());
                } else {
                    relationValue.setValue(price.add(new BigDecimal("0.05")).toString());
                }
                relationValueMapper.updateById(relationValue);
            }
        }
        sysUserMapper.updateById(sysUser);
    }
}
